import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import javax.swing.text.Style;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Scope {
    // 提取数字的正则表达式
    private static final Pattern number = Pattern.compile("(\\d+)");
    // 匹配经验的正则表达式
    private static final String regex = "^(互评 )?\\d+ 经验$";
    private static final Properties properties = new Properties();

    public static void main(String[] args)  {
        // 进行必要的参数检验
        if (args.length < 2) {
            System.out.println("缺少必要参数！");
            // 缺少参数直接退出
            return;
        }

        try {
            properties.load(new FileInputStream("total.properties"));
        } catch (IOException e) {
            // 解析错误，程序退出，并且打印错误信息
            e.printStackTrace();
            System.exit(-1);
        }

        // 调用方法获取两个页面的总成绩
        double scope = getAllScope(args[0]) + getAllScope(args[1]) + 6;
        System.out.println(scope);

    }

    /**
     * 提取span标签里面的经验值（已获得的）
     *
     * @param interactionRow 这个元素是包含一个活动的元素
     * @return 经验值
     */
    private static Double getScope(Element interactionRow) {
        // 通过正则表达式提取出包含经验值的 span标签元素 getElementsMatchingText()方法是通过正则判断子元素标签里的字符串是否跟正则表达式
        // 匹配，如果匹配就返回这个元素
        Elements elementsMatchingText = interactionRow.getElementsMatchingText(regex);
        // 根据文字颜色，判断是否是已获得的经验值
        if (!elementsMatchingText.attr("style").contains("color:#8FC31F;")) {
            return 0d;
        }
        // 提取经验值并返回
        String text = elementsMatchingText.text();
        Matcher matcher = number.matcher(text);
        if (matcher.find()) {
            return Double.parseDouble(matcher.group(1));
        }
        return 0d;
    }

    /**
     * 从property里面进行根据键取值并且转换成Double类型
     *
     * @param key 键
     * @return 类型转换过后的值
     */
    private static Double getDoubleProperty(String key) {
        return Double.parseDouble(properties.getProperty(key));
    }

    /**
     * 解析活动页面，返回换算过后的总成绩
     *
     * @param html html页面的路径
     * @return 换算过后的总成绩
     */
    public static Double getAllScope(String html)  {
        Document doc = null;
        try {
            doc = Jsoup.parse(new File(html), "utf-8");
        } catch (IOException e) {
            // 解析错误，程序退出，并且打印错误信息
            e.printStackTrace();
            System.exit(-1);
        }
        // 分析html可以发现每个活动都是由一个有 interaction-row 类名的标签元素包裹的
        Elements interactionRows = doc.getElementsByClass("interaction-row");


        double classScope = 0;
        double programScope = 0;
        double additionalScope = 0;
        double testScope = 0;
        double beforeScope = 0;

        // 遍历每个活动元素
        for (Element interactionRow : interactionRows) {
            // 拿到活动标题元素
            Element interactionName = interactionRow.getElementsByClass("interaction-name").get(0);
            String text = interactionName.text();
            // 根据标题判断是那种活动
            if (text.contains("课堂完成部分")) {

                classScope += getScope(interactionRow);
            }

            if (text.contains("编程题")) {

                programScope += getScope(interactionRow);
            }

            if (text.contains("附加题")) {
                additionalScope = getScope(interactionRow);
            }

            if (text.contains("课堂小测")) {
                testScope = getScope(interactionRow);
            }

            if (text.contains("课前自测")) {
                beforeScope = getScope(interactionRow);
            }
        }

        // 换算课堂完成部分的成绩
        double baseScope = getDoubleProperty("base");
        classScope = (classScope / baseScope) * 100 * .3 * .95;

        // 编程题成绩换算
        double program = getDoubleProperty("program");
        programScope = (programScope / program) * 95 * .1;

        // 附加题成绩换算
        double add = getDoubleProperty("add");
        additionalScope = (additionalScope / add) * 90 * .05;

        // 课前自测
        double before = getDoubleProperty("before");
        beforeScope = (beforeScope / before) * 100 * .25;

        // 课堂小测
        double test = getDoubleProperty("test");
        testScope = (testScope / test) * 100 * .2;

        // 返回总成绩
        return classScope + programScope + additionalScope + beforeScope + testScope;

    }
}
